package com.jcfk.system.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jcfk.common.business.enums.DeleteFlag;
import com.jcfk.common.business.power.annotation.DataPowerFilter;
import com.jcfk.common.business.service.BaseService;
import com.jcfk.common.core.exception.CustomException;
import com.jcfk.common.core.security.MyPasswordEncoder;
import com.jcfk.common.core.utils.BeanUtils;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.common.web.domain.DataPage;
import com.jcfk.common.web.domain.ReqPageParam;
import com.jcfk.common.web.domain.RetResult;
import com.jcfk.system.domain.dto.*;
import com.jcfk.system.dao.SysUserDao;
import com.jcfk.system.domain.po.RefUserOrganizationMapping;
import com.jcfk.system.domain.po.SysOrganization;
import com.jcfk.system.domain.po.SysUser;
import com.jcfk.system.domain.po.SysUserAccount;
import com.jcfk.system.domain.query.SysUserQuery;
import com.jcfk.system.domain.uploadExcel.SysUserUploadExcel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.jcfk.common.core.utils.BeanUtils.convertList;

/**
 * 用户管理 服务
 */
@Slf4j
@Service
public class SysUserService extends BaseService<SysUserDao, SysUser> {

    @Autowired
    private RefUserRoleMappingService refUserRoleMappingService;

    @Autowired
    private SysOrganizationService sysOrganizationService;

    @Autowired
    private RefUserOrganizationMappingService refUserOrganizationMappingService;

    @Autowired
    private SendWeChatService sendWeChatService;

    @Autowired
    private SysUserAccountService sysUserAccountService;

    /**
     * 根据条件获取用户分页列表
     *
     * @param page  分页设置
     * @param query 查询条件
     * @return 分页查询结果
     */
    //@DataPowerFilter(filterRule = "loginUserDataFilterRule",tableAlias="a",fieldAlias="created_user_id")
    public DataPage<SysUserDTO> queryByPage(DataPage<SysUserDTO> page, SysUserQuery query) {
        if (StrUtil.isNotEmpty(query.getFirstName())) {
            query.setFirstName("%" + query.getFirstName() + "%");
        }
        if (StrUtil.isNotEmpty(query.getLoginName())) {
            query.setLoginName("%" + query.getLoginName() + "%");
        }
        if (StrUtil.isNotEmpty(query.getDepartmentId())) {
            query.setDepartmentId("%"+query.getDepartmentId() + "%");
        }
        // 分页查询
        page = this.baseMapper.queryByPage(page, query);
        return page;
    }

    /**
     * 根据条件获取用户信息列表
     *
     * @param query 查询条件
     * @return List<SysUserDTO>
     */
    public List<SysUserDTO> getList(SysUserQuery query) {
        // 查询条件
        QueryWrapper<SysUser> qw = new QueryWrapper<>();
        if (!StrUtil.isEmpty(query.getEmpNo())) {
            qw.lambda().eq(SysUser::getEmpNo, query.getEmpNo());
        }
        if (!StrUtil.isEmpty(query.getDepartmentId())) {
            qw.lambda().eq(SysUser::getDepartmentId, query.getDepartmentId());
        }
        if (!StrUtil.isEmpty(query.getFirstName())) {
            qw.lambda().like(SysUser::getFirstName, query.getFirstName());
        }
        if (!StrUtil.isEmpty(query.getLoginName())) {
            qw.lambda().like(SysUser::getLoginName, query.getLoginName());
        }
        if (query.getEnabled() != null) {
            qw.lambda().eq(SysUser::getEnabled, query.getEnabled());
        }
        qw.lambda().eq(SysUser::getDeleted, 0);
        // 查询数据
        List<SysUser> list = super.list(qw);
        List<SysUserDTO> dtoList = new ArrayList<>();
        for (SysUser po : list) {
            SysUserDTO dto = new SysUserDTO();
            BeanUtils.copyProperties(po, dto);
            dto.setPassword(null);
            dtoList.add(dto);
        }
        return dtoList;
    }

    /**
     * 根据主键获取用户信息
     *
     * @param id 主键
     * @return StandardCodeDTO
     */
    public SysUserDTO get(String id) {
        // 查询数据
        SysUser item = this.baseMapper.selectById(id);
        SysUserDTO dto = new SysUserDTO();
        try {
            BeanUtils.copyProperties(item, dto);
        } catch (RuntimeException e) {
            throw e;
        }

        return dto;
    }

    /**
     * 插入用户
     *
     * @param dto 插入对象
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SysUserDTO insert(SysUserDTO dto) {

        // 默认数据
        dto.setVersion(1L);
        this.setDefaultValue(dto);
        dto.setOrganizationId(sysOrganizationService.getCompanyId(dto.getDepartmentId()));

        // 保存
        SysUser item = new SysUser();
        BeanUtils.copyProperties(dto, item);
        super.save(item);

        BeanUtils.copyProperties(item, dto);

        if (dto.getMobile() != null && !"".equals(dto.getMobile())) {
            String qiyeid = sendWeChatService.getUserId(sendWeChatService.getWXAccessToken(), dto.getMobile());
            SysUserAccount sysUserAccount = new SysUserAccount();
            sysUserAccount.setUserId(item.getId());
            sysUserAccount.setWecomId(qiyeid);
            sysUserAccountService.setDefaultValue(sysUserAccount);
            sysUserAccountService.save(sysUserAccount);
        }

        return dto;
    }

    /**
     * 更新用户
     *
     * @param dto 更新对象
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SysUserDTO update(SysUserDTO dto) {
        // 默认数据
        this.setDefaultValue(dto);
        dto.setOrganizationId(sysOrganizationService.getCompanyId(dto.getDepartmentId()));

        // 保存
        SysUser item = this.getById(dto.getId());
        dto.setPassword(item.getPassword());
        BeanUtils.copyProperties(dto, item);
        super.updateById(item);

        // 微信企业id
        if (dto.getMobile() != null && !"".equals(dto.getMobile())) {
            String qiyeid = sendWeChatService.getUserId(sendWeChatService.getWXAccessToken(), dto.getMobile());
            QueryWrapper<SysUserAccount> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUserAccount::getUserId, dto.getId());
            SysUserAccount sysUserAccount = sysUserAccountService.getOne(queryWrapper);
            if (sysUserAccount == null) sysUserAccount = new SysUserAccount();
            sysUserAccount.setUserId(dto.getId());
            sysUserAccount.setWecomId(qiyeid);
            sysUserAccountService.setDefaultValue(sysUserAccount);

            if (sysUserAccount.getId() != null && !"".equals(sysUserAccount.getId()))
                sysUserAccountService.updateById(sysUserAccount);
            else sysUserAccountService.save(sysUserAccount);
        } else {
            // 删除关联
            QueryWrapper<SysUserAccount> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysUserAccount::getUserId, dto.getId());
            SysUserAccount sysUserAccount = sysUserAccountService.getOne(queryWrapper);
            if (sysUserAccount != null) {
                sysUserAccount.setWecomId("");
                sysUserAccountService.updateById(sysUserAccount);
            }
        }
        BeanUtils.copyProperties(item, dto);
        return dto;
    }

    /**
     * 校验用户信息合法性
     *
     * @param dto
     * @return
     */
    public RetResult<String> isValid(SysUserDTO dto) {

        if (StrUtil.isEmpty(dto.getId())) {
            if (StrUtil.isEmpty(dto.getPassword())) {
                return RetResult.fail("密码不能为空");
            }
            if (StrUtil.isEmpty(dto.getRepeatPassword())) {
                return RetResult.fail("二次输入密码不能为空");
            }
            if (!dto.getPassword().equals(dto.getRepeatPassword())) {
                return RetResult.fail("二次输入密码不一致");
            }
        }

        Integer count = 0;

        // 判断登录名
        QueryWrapper<SysUser> qw = new QueryWrapper<>();
        if (!StrUtil.isEmpty(dto.getId())) {
            qw.lambda().ne(SysUser::getId, dto.getId());
        }
        qw.lambda().eq(SysUser::getLoginName, dto.getLoginName());
        qw.lambda().eq(SysUser::getDeleted, 0);

        count = this.baseMapper.selectCount(qw);
        if (count > 0) {
            return RetResult.fail("登录名已存在");
        }

        // 判断员工号
        if (StrUtil.isNotEmpty(dto.getEmpNo())) {
            qw = new QueryWrapper<>();
            if (!StrUtil.isEmpty(dto.getId())) {
                qw.lambda().ne(SysUser::getId, dto.getId());
            }
            qw.lambda().eq(SysUser::getEmpNo, dto.getEmpNo());
            qw.lambda().eq(SysUser::getDeleted, 0);

            count = this.baseMapper.selectCount(qw);
            if (count > 0) {
                return RetResult.fail("员工号已存在");
            }
        }

        return RetResult.ok();
    }

    /**
     * 根据主键删除用户(物理删除)
     *
     * @param dto
     * @return bool
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(SysUserDTO dto) {

        int count = this.baseMapper.deleteById(dto.getId());

        refUserRoleMappingService.deleteListByRole(dto.getId());

        return count > 0 ? true : false;
    }

    /**
     * 根据主键删除用户(逻辑删除)
     *
     * @param list
     * @return bool
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean logicDeleteList(SysUserDTO list) {
        Boolean result = false;
        // 删除主表
        UpdateWrapper<SysUser> uw = new UpdateWrapper<>();
        uw.lambda().in(SysUser::getId, list.getIds());
        uw.set("deleted", 1);
        result = this.update(uw);
        refUserRoleMappingService.deleteListByUser(list.getIds());
        return result;
    }

    /**
     * 根据主键设置用户密码
     *
     * @param dto
     * @return
     */
    public Boolean setPassWord(SysUserDTO dto) {
        Boolean result = false;
        // 删除主表
        UpdateWrapper<SysUser> uw = new UpdateWrapper<>();
        uw.lambda().eq(SysUser::getId, dto.getId());
        uw.set("password", dto.getPassword());
        result = this.update(uw);
        return result;
    }

    /**
     * 设置添加默认值
     *
     * @param dto 添加对象
     */
    public void setDefaultValue(SysUserDTO dto) {
        if (StrUtil.isEmpty(dto.getCreatedUserId())) {
            dto.setCreatedUserId(SecurityUtils.getUserId());
            dto.setCreatedUserName(SecurityUtils.getUserName());
            dto.setCreateTime(new Date());
        }
        dto.setLastUpdatedUserId(SecurityUtils.getUserId());
        dto.setLastUpdatedUserName(SecurityUtils.getUserName());
        dto.setLastUpdateTime(new Date());
        dto.setDeleted(0);
    }

    /**
     * 根据主键获取用户信息
     *
     * @param userRestParameter 重置密码
     */
    public void rest(UserRestParameter userRestParameter) {
        // 查询数据
        SysUser item = this.baseMapper.selectById(userRestParameter.getId());

        if (item == null) throw new RuntimeException("用户不存在");

        item.setPassword(MyPasswordEncoder.getInstance().encode(userRestParameter.getPassWord()));
        item.setLastUpdatedUserId(SecurityUtils.getUserId());
        item.setLastUpdateTime(new Date());
        this.updateById(item);
    }

    /**
     * 可用用户分页查询
     * @param page
     * @param query
     * @return
     */
    public DataPage<SysUserVo> listByPage(DataPage<SysUserVo> page, UserOrganizationParameter query) {
        if (StrUtil.isNotEmpty(query.getUserName())) {
            query.setUserName(query.getUserName() + "%");
        }
        if (StrUtil.isNotEmpty(query.getOrganizationId())) {
            query.setOrganizationId("%"+query.getOrganizationId() + "%");
        }
        // 分页查询
        page = this.baseMapper.listByPage(page, query);
        return page;
    }

//    public IPage<SysUser> getLsit(ReqPageParam<UserOrganizationParameter> requestParam) {
//        ReqPageParam<SysUser> reqPageParam = new ReqPageParam<>();
//
//        reqPageParam.setCurrent(requestParam.getCurrent());
//        reqPageParam.setSize(requestParam.getSize());
//
//        UserOrganizationParameter parameter = requestParam.getData();
//        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
//        queryWrapper.lambda().like(!StringUtils.isEmpty(parameter.getEmpNo()), SysUser::getEmpNo, parameter.getEmpNo()).like(!StringUtils.isEmpty(parameter.getUserName()), SysUser::getFirstName, parameter.getUserName()).eq(SysUser::getEnabled, 1).eq(SysUser::getDeleted, 0);
//        if (!StringUtils.isEmpty(parameter.getOrganizationId())) {
//            SysOrganization sysOrganization = sysOrganizationService.getById(parameter.getOrganizationId());
//            if (sysOrganization != null) {
//                LambdaQueryWrapper<SysOrganization> wrapper = Wrappers.lambdaQuery(SysOrganization.class);
//                wrapper.likeRight(SysOrganization::getAllId, sysOrganization.getAllId());
//                List<SysOrganization> list = sysOrganizationService.list(wrapper);
//
//                // 所有组织的ids
//                List<String> ids = list.stream().map(SysOrganization::getId).collect(Collectors.toList());
//
//                if (ids.size() > 0) {
//                    List<RefUserOrganizationMapping> refUserOrganizationMappings = refUserOrganizationMappingService.list(Wrappers.lambdaQuery(RefUserOrganizationMapping.class).in(ids.size() > 0, RefUserOrganizationMapping::getOrganizationId, ids));
//
//                    List<String> userids = refUserOrganizationMappings.stream().map(RefUserOrganizationMapping::getUserId).collect(Collectors.toList());
//                    if (userids.size() == 0) return new Page<>(reqPageParam.getCurrent(), reqPageParam.getSize());
//                    // 根据用户id查询
//                    queryWrapper.lambda().in(SysUser::getId, userids);
//                }
//
//            } else {
//                return new Page<>(reqPageParam.getCurrent(), reqPageParam.getSize());
//            }
//        }
//        IPage<SysUser> page = this.getPageData(reqPageParam, queryWrapper);
//        return page;
//    }


    /**
     * 根据员工号获取员工id
     *
     * @param ids 根据员工号获取员工id
     */

    public List<String> getUseridsForUserNo(List<String> ids) {
        List<String> userIds = new ArrayList<>();
        if (ids.size() <= 0) {
            return userIds;
        }

        QueryWrapper<SysUser> qw = new QueryWrapper<>();
        qw.lambda().in(SysUser::getEmpNo, ids);
        qw.lambda().eq(SysUser::getDeleted, DeleteFlag.NOTDELETED.getValue());

        List<SysUser> users = this.baseMapper.selectList(qw);
        userIds = users.stream().map(SysUser::getId).collect(Collectors.toList());

        return userIds;

    }

    /**
     * 根据员工号获取员工电话号
     *
     * @param ids 根据员工号获取员工电话号
     */

    public List<String> getPhoneListForUserNo(List<String> ids) {
        List<String> phoneList = new ArrayList<>();
        if (ids.size() <= 0) {
            return phoneList;
        }

        QueryWrapper<SysUser> qw = new QueryWrapper<>();
        qw.lambda().in(SysUser::getEmpNo, ids);

        List<SysUser> users = this.baseMapper.selectList(qw);
        phoneList = users.stream().map(SysUser::getPhone).collect(Collectors.toList());

        return phoneList;

    }

    /**
     * 根据组织id和角色id获取用户信息
     * @param organizationIds 组织id
     * @param roleIds 角色信息
     * @return 用户信息
     */
    public List<SysUser> queryUsersByOrganAndRole(List<String> organizationIds, List<String> roleIds) {
        return this.baseMapper.queryUsersByOrganAndRole(organizationIds, roleIds);
    }
    @Transactional
    public void insertBatch(List<SysUserUploadExcel> excelList) {
        if (excelList == null || excelList.isEmpty()){
            throw new CustomException("请选择要导入的Excel文件");
        }
        List<SysUser> list = new ArrayList<>();
        for (SysUserUploadExcel user : excelList) {
            if (StrUtil.isBlank(user.getEmpNo())){
                throw new CustomException("员工工号不能为空");
            }
            if (StrUtil.isBlank(user.getDepartmentName())){
                throw new CustomException("部门名称不能为空");
            }
            if (StrUtil.isBlank(user.getLoginName())){
                throw new CustomException("登录名不能为空");
            }
            if (StrUtil.isBlank(user.getFirstName())){
                throw new CustomException("用户名不能为空");
            }
            //员工号存在跳过
            QueryWrapper<SysUser> qwuser = new QueryWrapper<>();
            qwuser.lambda().eq(SysUser::getEmpNo, user.getEmpNo());
            List<SysUser> userList = this.list(qwuser);
            if (!userList.isEmpty()) {
                continue;
            }
            SysUser sysUser = new SysUser();
            sysUser.setEmpNo(user.getEmpNo());
            sysUser.setLoginName(user.getLoginName());
            sysUser.setFirstName(user.getFirstName());
            QueryWrapper<SysOrganization> qw = new QueryWrapper<>();
            qw.lambda().eq(SysOrganization::getOrganizationName, user.getDepartmentName());
            List<SysOrganization> organizations = sysOrganizationService.list(qw);
            if (!organizations.isEmpty()) {
                sysUser.setDepartmentId(organizations.get(0).getId());
                sysUser.setOrganizationId(sysOrganizationService.getCompanyId(organizations.get(0).getId()));
            } else {
                throw new CustomException("部门名称不存在");
            }
            sysUser.setPassword(MyPasswordEncoder.getInstance().encode(user.getEmpNo() + "abc"));
            sysUser.setUserType("ordinaryuser");
            sysUser.setEnabled(1);
            Date date = new Date();
            sysUser.setCreatedUserId("1");
            sysUser.setCreateTime(date);
            sysUser.setLastUpdatedUserId("1");
            sysUser.setLastUpdateTime(date);
            sysUser.setDeleted(0);
            sysUser.setVersion(1L);
            list.add(sysUser);
        }
        this.saveBatch(list);
    }

    /**
     * 根据角色id获取用户信息
     * @param roleIds 角色id
     * @return 用户信息
     */
    public List<SysUserWithRoleIdDTO> getUserListByRoleIds(List<String> roleIds) {
        return this.baseMapper.getUserListByRoleIds(roleIds);
    }
}
